/**
 * Copyright (C), 2015-2019, bogewang
 * FileName: MemberLoginServiceImpl
 * Author:   foren236598164@aliyun.com
 * Date:     2019/9/16 14:16
 * Description: 登录实现类
 * History:
 * <author>          <time>          <version>          <desc>
 * 作者姓名           修改时间           版本号              描述
 */
package com.bogewang.member.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.bogewang.core.base.BaseApiService;
import com.bogewang.core.base.BaseResponse;
import com.bogewang.core.constants.Constants;
import com.bogewang.core.core.token.TokenUtils;
import com.bogewang.core.core.transaction.RedisDataSoureceTransaction;
import com.bogewang.core.core.utils.MD5Util;
import com.bogewang.member.entity.LoginDTO;
import com.bogewang.member.entity.UserDTO;
import com.bogewang.member.mapper.LoginTokenMapper;
import com.bogewang.member.mapper.UserMapper;
import com.bogewang.member.service.MemberLoginService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.TransactionStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

/**
 * 〈登录实现类〉
 *
 * @author foren236598164@aliyun.com
 * @create 2019/9/16
 * @since 1.0.0
 */
@RestController
public class MemberLoginServiceImpl extends BaseApiService<JSONObject> implements MemberLoginService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private LoginTokenMapper tokenMapper;

    @Autowired
    private TokenUtils tokenUtils;

    @Autowired
    private RedisDataSoureceTransaction redisDataSoureceTransaction;

    @Override
    public BaseResponse<JSONObject> login(@RequestBody LoginDTO loginDTO) {
        // 1.验证参数;
        String mobile = loginDTO.getMobile();
        if (isBlank(mobile)){
            return setResultError("手机号码不能为空!");
        }

        String password = loginDTO.getPassword();
        if (isBlank(password)){
            return setResultError("密码不能为空!");
        }

        String loginType = loginDTO.getLoginType();
        if (isBlank(loginType)){
            return setResultError("登录类型不能为空!");
        }

        if (!(loginType.equals(Constants.MEMBER_LOGIN_TYPE_ANDROID) ||loginType.equals(Constants.MEMBER_LOGIN_TYPE_IOS) ||
                loginType.equals(Constants.MEMBER_LOGIN_TYPE_PC))){
            return setResultError("登录类型错误!");
        }

        String deviceInfo = loginDTO.getDeviceInfo();
        if (isBlank(deviceInfo)){
            return setResultError("登录设备信息不能为空!");
        }

        // 2.密码加密;
        String newPassword = MD5Util.MD5(password);
        // 3. 查询用户是否存在;
        UserDTO userDTO = userMapper.login(mobile, newPassword);
        if (userDTO == null){
            return setResultError("用户名或者密码错误!");
        }

        // 4.查询当前登录类型账号是否有登陆过;
        Long userid = userDTO.getUserid();
        LoginDTO hasLoginDTO = tokenMapper.selectByUserIdAndLoginType(userid, loginType);

        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = redisDataSoureceTransaction.begin();
            if (hasLoginDTO != null){
                String token = hasLoginDTO.getToken();
                tokenUtils.removeToken(token);
                int updateTokenAvailable = tokenMapper.updateTokenAvailable(token);
                if (!toDaoResult(updateTokenAvailable)){
                    return setResultError("系统错误!");
                }
            }

            // 如果有传递openid参数，修改到数据中
            String qqOpenId = loginDTO.getQqOpenId();
            if (isBlank(qqOpenId)){
                userMapper.updateUserOpenId(qqOpenId, userid);
            }

            // 6.插入新的token
            LoginDTO newLoginDTO = new LoginDTO();
            newLoginDTO.setUserId(userid);
            newLoginDTO.setLoginType(loginDTO.getLoginType());

            // 5.生成对应用户令牌存放在redis中;
            String keyPrefix = Constants.MEMBER_TOKEN_KEYPREFIX + loginType;
            String newToken = tokenUtils.createToken(keyPrefix, userid + "");
            newLoginDTO.setToken(newToken);
            newLoginDTO.setDeviceInfo(deviceInfo);
            int insertUserToken = tokenMapper.insertUserToken(newLoginDTO);
            if (!toDaoResult(insertUserToken)){
                return setResultError("系统错误!");
            }
            JSONObject data = new JSONObject();
            data.put("token", newToken);

            redisDataSoureceTransaction.commit(transactionStatus);
            return setResultSuccess(data);
        } catch (Exception e) {
            try {
                redisDataSoureceTransaction.rollback(transactionStatus);
            } catch (Exception e2) {
                // TODO: handle exception
            }
            return setResultError("系统错误!");
        }
    }

    @Override
    public BaseResponse<JSONObject> loginOut(String token) {
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = redisDataSoureceTransaction.begin();
            //2.从数据库更新状态;
            int updateTokenAvailable = tokenMapper.updateTokenAvailable(token);
            if (!toDaoResult(updateTokenAvailable)){
                return setResultError("系统错误!");
            }
            //3.从redis中删除token
            tokenUtils.removeToken(token);
            redisDataSoureceTransaction.commit(transactionStatus);
            return setResultSuccess("登出成功!");
        } catch (Exception e) {
            try {
                redisDataSoureceTransaction.rollback(transactionStatus);
            } catch (Exception e2) {
                e2.printStackTrace();
            }
            e.printStackTrace();
            return setResultError("系统错误!");
        }
    }
}